//
// Created on 2024/10/23.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#include "Audio.h"
#include <chrono>

FILE *Lal0haudio::file = nullptr;

Lal0haudio::Lal0haudio() {
    file = nullptr;
    audioRenderer = nullptr;
    rendererBuilder = nullptr;
    filePath  = "/data/storage/el2/base/haps/entry/files/444.raw";
    samplingRate = 44100;
    channelCount = 2;
}

Lal0haudio::~Lal0haudio()
{
    
}

int32_t  Lal0haudio::AudioRendererOnWriteData(OH_AudioRenderer *renderer, void *userData, void *buffer, int32_t bufferLen) {
    Lal0haudio *lal0haudio = reinterpret_cast<Lal0haudio *>(userData);
    fread(buffer, bufferLen, 1, file);
    int64_t framePosition;
    int64_t timestamp;
    auto now2 = std::chrono::high_resolution_clock::now();
    OH_AudioRenderer_GetTimestamp(lal0haudio->audioRenderer,CLOCK_MONOTONIC,&framePosition,&timestamp);
    auto now = std::chrono::high_resolution_clock::now();
    OH_LOG_ERROR(LOG_APP, "\n获取的数据%{public}d  timestamp:%{public}lld  系统时间:%{public}lld 最先系统时间:%{public}lld\n",framePosition,timestamp,now,now2);
    return 0;
}

int Lal0haudio::GetRendererState() {
    OH_AudioStream_State state;
    OH_AudioRenderer_GetCurrentState(audioRenderer, &state);
    return state;
}

int Lal0haudio::AudioRendererInit(bool  LowLatency) {
    if (audioRenderer) {
        OH_AudioRenderer_Release(audioRenderer);
        OH_AudioStreamBuilder_Destroy(rendererBuilder);
        audioRenderer = nullptr;
        rendererBuilder = nullptr;
    }
    if (file) {
        fclose(file);
        file = nullptr;
    }
    file = fopen(filePath.c_str(), "rb");
    if (file == nullptr) {
        return 0;
    }
    
    // create builder
    OH_AudioStream_Type type = AUDIOSTREAM_TYPE_RENDERER;
    OH_AudioStreamBuilder_Create(&rendererBuilder, type);

    // set params and callbacks
    OH_AudioStreamBuilder_SetSamplingRate(rendererBuilder, samplingRate);
    OH_AudioStreamBuilder_SetChannelCount(rendererBuilder, channelCount);
    // 设置音频采样格式
    OH_AudioStreamBuilder_SetSampleFormat(rendererBuilder, AUDIOSTREAM_SAMPLE_S16LE);
    // 设置音频流的编码类型
    OH_AudioStreamBuilder_SetEncodingType(rendererBuilder, AUDIOSTREAM_ENCODING_TYPE_RAW);
    // 设置输出音频流的工作场景
    OH_AudioStreamBuilder_SetRendererInfo(rendererBuilder, AUDIOSTREAM_USAGE_MUSIC);
    if(LowLatency)
    {
        OH_AudioStreamBuilder_SetLatencyMode(rendererBuilder, AUDIOSTREAM_LATENCY_MODE_FAST);
    } else{
        OH_AudioStreamBuilder_SetLatencyMode(rendererBuilder, AUDIOSTREAM_LATENCY_MODE_NORMAL);
        OH_AudioStreamBuilder_SetFrameSizeInCallback(rendererBuilder, 100);
    }
    OH_AudioRenderer_Callbacks rendererCallbacks;
    rendererCallbacks.OH_AudioRenderer_OnWriteData = AudioRendererOnWriteData;
    rendererCallbacks.OH_AudioRenderer_OnStreamEvent = nullptr;
    rendererCallbacks.OH_AudioRenderer_OnInterruptEvent = nullptr;
    rendererCallbacks.OH_AudioRenderer_OnError = nullptr;
    OH_AudioStreamBuilder_SetRendererCallback(rendererBuilder, rendererCallbacks, this);
    // create OH_AudioRenderer
    OH_AudioStreamBuilder_GenerateRenderer(rendererBuilder, &audioRenderer);
    return 0;
}


//查询自创建流以来已写入的帧数
int64_t Lal0haudio::GetFramesWritten() {
    int64_t frames;
    OH_AudioRenderer_GetFramesWritten(audioRenderer, &frames);
    return frames;
}


int32_t Lal0haudio::AudioRendererStart() {
    OH_AudioStream_Result info;
    info = OH_AudioRenderer_Start(audioRenderer);
    return info;
}

int32_t Lal0haudio::AudioRendererPause() {
    OH_AudioStream_Result info;
    info = OH_AudioRenderer_Pause(audioRenderer);
    return info;
}

int32_t Lal0haudio::AudioRendererStop() {
    OH_AudioStream_Result info;
    info = OH_AudioRenderer_Stop(audioRenderer);
    return info;
}    

//释放资源
int32_t Lal0haudio::AudioRendererRelease() {
    if (audioRenderer) {
        OH_AudioRenderer_Release(audioRenderer);
        OH_AudioStreamBuilder_Destroy(rendererBuilder);
        audioRenderer = nullptr;
        rendererBuilder = nullptr;
    }
    if (file) {
        fclose(file);
        file = nullptr;
    }
    return 0;
}

 int32_t Lal0haudio::Update() {
    
     return 0;
}